home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Games of Daze
/
Infomagic - Games of Daze (Summer 1995) (Disc 1 of 2).iso
/
x2ftp
/
msdos
/
utils
/
pcxutils
/
pcx2fnt.c
< prev
next >
Wrap
C/C++ Source or Header
|
1993-07-14
|
13KB
|
481 lines
/**************************************************************************
PCX2FNT - by Lee Hamel (Patch), hamell@cx.pdx.edu, *Avalanche* coder
July 14th, 1993
**************************************************************************/
#include <stdio.h>
#include <string.h>
#include <malloc.h>
#undef DEBUG1
#undef DEBUG2
#undef DEBUG3
#undef DEBUG4
#undef DEBUG5
#undef DEBUG6
#undef DEBUG7
#undef DEBUG8
#undef DEBUG9
typedef struct {
char manufacturer;
char version;
char encoding;
char bits_per_pixel;
int xmin,ymin;
int xmax,ymax;
int hres;
int vres;
char palette[48];
char reserved;
char colour_planes;
int bytes_per_line;
int palette_type;
char filler[58];
} PCXHEAD;
#define PCXHEADSIZE sizeof(PCXHEAD)
PCXHEAD header;
unsigned int width, depth, bytes, i, i1, i2, i3, charcount = 0;
unsigned char palette[768];
unsigned char charrows, charsinrow[20], numcolors = 0, startcolor = 0;
unsigned char buffer[256], charorder[256], xysizes[512], showflag;
FILE *infile, *outfile;
unsigned char *tempptr, *charptr, *rowptr, *picture, *fonts[256];
char pcxfile[20],cfgfile[20],fntfile[20],asmfile[20];
void Read_PCX_Line(unsigned int vidoffset)
{
unsigned char c, run;
unsigned int n = 0;
_asm
{
cld
mov di,[vidoffset]
}
do
{
c = fgetc(infile) & 0xff;
if ((c & 0xc0) == 0xc0) /* if it's a run of bytes field */
{
run = c & 0x3f; /* and off the high bits */
c = fgetc(infile); /* get the run byte */
n += run; /* run the byte */
buffer[c] = 1;
for (i2 = 0; i2 < run; i2++)
*picture++ = c;
if (showflag == 0)
{
_asm
{
mov ax,0a000h
mov es,ax
mov al,[c]
xor ch,ch
mov cl,[run]
rep stosb
}
}
}
else
{
n++;
buffer[c] = 1;
*picture++ = c;
if (showflag == 0)
{
_asm
{
mov ax,0a000h
mov es,ax
mov al,[c]
stosb
}
}
}
}
while (n < bytes);
}
void Unpack_PCX_File(void)
{
for (i = 0; i < 768; i++)
palette[i] = palette[i] >> 2;
if (showflag == 0)
{
_asm
{
mov ax,0013h
int 10h
mov ax,1012h
xor bx,bx
mov cx,256
mov dx,offset palette
int 10h
}
}
rowptr = picture = (unsigned char *) malloc((size_t) 64000);
for (i = 0; i < depth; i++)
Read_PCX_Line(i * 320);
}
void Get_CFG_File(char *cfgfile)
{
char tempstr[80],temp1[5],temp2[5],num[5];
FILE *fp;
for (i = 0; i < 512; i++)
xysizes[i] = 0;
i = 0;
if ((fp = fopen(cfgfile,"rt")) != NULL)
{
do
{
fgets(tempstr,80,fp);
}
while (tempstr[0] == ';' || tempstr[0] == '\n');
#ifdef DEBUG8
printf("Tempstr[0] and [1] = [%d] [%d]\n",tempstr[0],tempstr[1]);
#endif
sscanf(tempstr,"%s = %d",tempptr,& charrows);
fgets(tempstr,80,fp);
tempptr = strchr(tempstr,'=');
tempptr += 2;
#ifdef DEBUG8
printf("Charrows = [%d]\n",charrows);
#endif
for (i = 0; i < charrows; i++)
{
sscanf(tempptr,"%d",& charsinrow[i]);
#ifdef DEBUG8
printf("Charsinrow[%d] = [%d]\n",i,charsinrow[i]);
#endif
while (*tempptr != ' ') tempptr++;
tempptr++;
}
i = 0;
while (fgets(tempstr,80,fp) != NULL)
{
if (tempstr[0] != ';' && tempstr[0] != '\n')
{
if (sscanf(tempstr,"%s = %s x %s",num,temp1,temp2) != -1)
{
#ifdef DEBUG1
printf("Num = [%s], Temp1 = [%s], Temp2 = [%s]\n",
num,temp1,temp2);
#endif
charorder[i++] = atoi(num);
charcount++;
xysizes[2*atoi(num) + 0] = atoi(temp1);
xysizes[2*atoi(num) + 1] = atoi(temp2);
}
}
}
fclose(fp);
}
else
{
fcloseall();
printf("Could not open file %s\n",cfgfile);
exit(1);
}
#ifdef DEBUG1
for (i = 0; i < 256; i++)
printf("Index[%3d] = x(%d), y(%d)\n",i,xysizes[i*2],xysizes[(i*2)+1]);
#endif
}
void Dump_Fonts(void)
{
unsigned int ord = 0, xsize, ysize, highesty;
#ifdef DEBUG4
for (i = 0; i < 256; i++)
{
fonts[i] = (char *) malloc((size_t) 2);
*fonts[i] = i;
*(fonts[i] + 1) = i + 1;
}
for (i = 0; i < 256; i++)
printf("Fonts[%d] = %d %d\n",i,*fonts[i],*(fonts[i]+1));
free((char *) fonts);
return;
#endif
#ifdef DEBUG5
for (ord = 0; ord < charcount; ord++)
printf("char [%c] [%3d] x-size = %2d\ty-size = %2d\n",
charorder[ord], charorder[ord],
xysizes[charorder[ord]*2],
xysizes[(charorder[ord]*2)+1]);
return;
#endif
#ifdef DEBUG6
picture = rowptr + 320;
for (i = 0; i < xysizes[charorder[ord]*2]; i++)
printf("Bitmap = %3d\n",*picture++);
return;
#endif
for (i = 0; i < charrows; i++)
{
/* reset pointer to UL corner of character row */
/* +320 to skip over blank row */
highesty = 0; /* longest font initialize */
rowptr += 320;
picture = rowptr;
for (i3 = 0; i3 < charsinrow[i]; i3++)
{
/* UL corner of char */
charptr = picture;
xsize = xysizes[charorder[ord]*2];
ysize = xysizes[(charorder[ord]*2)+1];
#ifdef DEBUG9
printf("Ord = [%d] Charorder[ord] = [%d]\n",
ord,charorder[ord]);
printf("Xsize = [%d] Ysize = [%d]\n",xsize,ysize);
#endif
if (ysize > highesty) highesty = ysize;
tempptr = fonts[charorder[ord]] =
(unsigned char *) malloc((size_t) xsize * ysize);
for (i1 = 0; i1 < xsize; i1++) /* X value */
{
for (i2 = 0; i2 < ysize; i2++) /* Y value */
{
*tempptr++ = *picture;
picture += 320;
}
picture++; /* next column over */
picture -= 320*ysize; /* back to top of column */
}
ord++; /* next char in order */
picture = charptr + xsize + 1; /* jump to next UL corner */
}
/* Jump to start of next char row */
rowptr += (320 * highesty);
#ifdef DEBUG7
printf("Ord = [%u] Highesty = [%u]\n",
ord, highesty);
#endif
}
i1 = 1285;
for (i = 0; i < 256; i++)
{
xsize = xysizes[i*2];
ysize = xysizes[(i*2)+1];
fwrite(&i1, 2, 1, outfile);
i1 += (xysizes[i * 2] * xysizes[(i * 2) + 1]) + 3;
}
for (i = 0; i < 256; i++)
{
xsize = xysizes[i*2];
ysize = xysizes[(i*2)+1];
if (xsize == 0 && ysize == 0)
fprintf(outfile,"%c%c%c",i,0,0);
else
{
fprintf(outfile,"%c%c%c",i,xsize,ysize);
for (i1 = 0, charptr = fonts[i]; i1 < xsize * ysize; i1++)
fprintf(outfile,"%c",*charptr++);
}
}
for (i = 0; i < charcount; i++)
free((unsigned char *) fonts[i]);
}
void Help(char helptype)
{
printf("\n");
printf("PCX2FNT - Converts a PCX pic to FNT format\n");
printf(" by Patch (hamell@rigel.cs.pdx.edu) \n");
printf("──────────────────────────────────────────\n");
if (helptype == 1)
{
printf("FNT format\n");
printf("──────────\n");
printf("byte 00h - 02h : string signature 'LMH' (for error checking)\n");
printf("byte 03h : # of colors used by the fonts\n");
printf("byte 04h : starting palette color used by the fonts\n");
printf("byte 05h - 772 : RGB data for 256 possible colors\n");
printf("word 773 - 1284: offset of all 256 ASCII chars, relative to byte 0\n");
printf("byte 1285 - : data for the fonts\n");
printf(" 1st byte is the char in the ASCII table\n");
printf(" 2nd byte is the X size (width)\n");
printf(" 3rd byte is the Y size (height)\n");
printf(" X*Y bytes of the font - saved column by column\n");
printf(" top to bottom, left to right\n\n");
printf("Fonts are expected to be in the following format:\n");
printf("┌─┬─┬─┬─┬─┬──┬──── Note the 0s along the top row and far right column.\n");
printf("0 0 0 0 0 0 ─┤ This is an example of the pixel placement of an A.\n");
printf("0 1 1 1 0 0 ─┤ The 1s represent where the different colors are at.\n");
printf("1 1 1 1 1 0 ─┤ When drawing the fonts, make sure each lettter has a\n");
printf("1 1 0 1 1 0 ─┤ border along the top side, otherwise the conversion\n");
printf("1 1 1 1 1 0 ─┤ algorithm will mess up. Just stack all of your fonts\n");
printf("1 1 0 1 1 0 ─┤ on top of each other and side by side, save the picture\n");
printf("1 1 0 1 1 0 ─┤ as a PCX, and you're done!\n");
}
else
{
printf("Usage: pcx2fnt [-FNT] PCXFILE [-SHOW]\n");
printf("where: -FNT - show the FNT format\n");
printf(" PCXFILE - the PCX file to read (no extension)\n");
printf(" -SHOW - show the PCX on the screen\n\n");
printf("Example call: pcx2fnt fontfile -show\n");
printf("- This will read the file FONTFILE, show it to the screen, and\n");
printf(" will read the configuration information from FONTFILE.CFG.\n\n");
printf("Example FONTFILE.CFG:\n");
printf("charrows = 4\n");
printf("charsinrow = 3 4 5 6\n");
printf("065 = 10 x 10\n\n");
printf("The program expects 4 rows of fonts with 3 fonts in the 1st row, 4 in the 2nd,\n");
printf("5 in the 3rd, and 6 in the 4th. 065 represents ASCII char A, and it is a\n");
printf("10 x 10 bitmap. The file FONTFILE.FNT will be created. Use a paint\n\n");
printf("program to figure out the pixel count. The blank border along the top and right\n");
printf("of each font DOES NOT count as part of the height or width!\n");
}
exit(1);
}
void main(int argc, char *argv[])
{
if (stricmp("-FNT",argv[1]) == 0) Help(1);
if (argc == 1) Help(0);
{
strcpy(pcxfile,argv[1]);
strcpy(cfgfile,argv[1]);
strcpy(fntfile,argv[1]);
strcpy(asmfile,argv[1]);
strcat(pcxfile,".pcx");
strcat(cfgfile,".cfg");
strcat(fntfile,".fnt");
strcat(asmfile,".asm");
if ((infile = fopen(pcxfile,"rb")) != NULL)
{
if (fread((char *)&header,1,PCXHEADSIZE,infile) == PCXHEADSIZE)
{
if (header.manufacturer == 0x0a && header.version == 5)
{
if (!fseek(infile,-769L,SEEK_END))
{
if (fgetc(infile) == 0x0c && fread(palette,1,768,infile) == 768)
{
fseek(infile,128L,SEEK_SET);
width = header.xmax - header.xmin + 1;
depth = header.ymax - header.ymin + 1;
bytes = header.bytes_per_line;
/*
printf("Width = %d\n",width);
printf("Depth = %d\n",depth);
printf("Bytes = %d\n",bytes);
printf("Chars per row = %d\n",charsrow);
*/
showflag = stricmp("-SHOW",argv[2]);
Get_CFG_File(cfgfile);
Unpack_PCX_File();
#ifdef DEBUG2
for (i = 0; i < 256; i++)
printf("Charorder[%3d] = %d\n",i,charorder[i]);
#endif
#ifdef DEBUG3
for (i = 0; i < 256; i++)
printf("Buffer[%3d] = %d\n",i,buffer[i]);
#endif
outfile = fopen(fntfile,"wb");
for (i = 1; i < 255; i++) /* ignore use of colors 0 and 255 */
if (buffer[i] == 1) numcolors++;
for (i = 1; i < 255; i++) /* ignore use of colors 0 and 255 */
if (startcolor != 0) break;
else if (buffer[i] == 1) startcolor = i;
fprintf(outfile,"LMH");
fprintf(outfile,"%c%c",numcolors,startcolor);
for (i = 0; i < 256; i++)
{
fprintf(outfile,"%c%c%c",palette[(i*3)+0],
palette[(i*3)+1],
palette[(i*3)+2]);
}
Dump_Fonts();
fclose(outfile);
/*
outfile = fopen(asmfile,"wt");
fprintf(outfile,"fontpos ");
i1 = 5;
for (i = 0; i < 256; i++)
{
// (X value * Y values) + 3 byte ASCII char,
// X,Y header for each char
fprintf(outfile,"dw %5u ; ASCII num %3d, char %c\n ",
i1,i,(i >= 32 ? i: ' '));
i1 += (xysizes[i * 2] * xysizes[(i * 2) + 1]) + 3;
}
*/
fclose(outfile);
if (showflag == 0)
{
_asm
{
xor ax,ax
int 16h
mov ax,0003h
int 10h
}
}
free((unsigned char *) picture);
}
else printf("Error reading palette\n");
}
else printf("Error seeking to palette\n");
}
else printf("Not a 256 color PCX file\n");
}
else printf("Error reading %s\n",argv[4]);
fclose(infile);
}
else printf("Error opening %s\n",argv[4]);
}
}